﻿var WIDTH = 130;
var refreshTimerMsec = 4000;
var refreshWebTimerMsec =86400000; // refresh once every day
var ICON_WIDTH = 16;
var ICON_HEIGHT = 16;	

var defaultSettings = [];                 // Store default settings in array
defaultSettings['updateAvailable']=false;
defaultSettings['numItems'] = 9;     

var iconPath = [] ;	//paths to the hard coded file icons
iconPath['pdf']="..\\images\\icons\\AcroRd32_2.ico";
iconPath['gif']=iconPath['jpg']=iconPath['png']=iconPath['bmp']="..\\images\\icons\\PhotoAcq_1079.ico";
iconPath['pptx']=iconPath['ppt']="..\\images\\icons\\POWERPNT_1300.ico";
iconPath['mpg']=iconPath['avi']=iconPath['mpeg']=iconPath['mp4']=iconPath['wmv']=iconPath['divx']="..\\images\\icons\\shell32_224.ico";
iconPath['folder']="..\\images\\icons\\shell32_4.ico";
iconPath['network']="..\\images\\icons\\shell32_16781.ico";

IMG_ITEM_HIGHLIGHT="..\\images\\highlight.png";
IMG_PIN_HIGHLIGHT="..\\images\\pin_background.png";
var PIN_WIDTH = 20;
var PIN_HEIGHT = 20;

var recentItemsObj=new folderItems( System.Shell.knownFolderPath("Profile")+"\\AppData\\Roaming\\Microsoft\\Windows\\Recent");
var webContentObj = new webContent("http://www.freewebs.com/recentitems/gadgetv1_1_0_1.htm");//"http://www.freewebs.com/recentitems/gadgetv1_0.htm");
var STR_NO_RECENT_ITEMS = "No recent documents to show. As you open begin using documents, they will start appearing here.";

function init()
{
	// set default settings
	if (System.Gadget.Settings.read("numItems") == '') // if none found, return default settings
	{
		System.Gadget.Settings.write("numItems",defaultSettings['numItems']);
	}
	
	// perform first update
	recentItemsObj.refresh();	// update data	
	webContentObj.updateWebContent();	//update web data
	populate();	// update ui

	checkDockState(); // check the initial state
	
	// setup the event handlers for docking later
	System.Gadget.onDock = dockGadget;
	System.Gadget.onUndock = undockGadget;
	
	// setup event handlers to apply settings that have been changed
	System.Gadget.onSettingsClosed = applySettings;
		
	// if using a flyout function, set the
	

} 

function dropItem()
{
    recentItemsObj.pinPath(event.dataTransfer);
}

/**
 * Called when settings dialog is closed
 */
function applySettings(event)
{
	if (event.closeAction == event.Action.commit)
	{
		recentItemsObj.refresh();	// refresh data
		populate();	// force refrsh UI
		checkDockState(); // redraw the gadget depending on the state
	}
	
	
}

function populate()
{
	// set the links to the most recent item
	var oldUlElement =  document.getElementById("linksList");
	var ulElement = document.createElement("div");
	
	var newHeight = recentItemsObj.pathList.length*20+12; //num of items*height of each item + upper and lower gap
	
	for (var i in recentItemsObj.pathList) // for each file item	
	{
		// grab file details
		var mostRecentFile = recentItemsObj.pathList[i];	// grab the file item
		var fileName = mostRecentFile.name;	// grab the file's name
		// grab the file's location in a link
		var linkSrc = "javascript:executeCommand(\""+encodeURIComponent(mostRecentFile.path)+"\");";	

		// create the DOM elements 
//		<div id="linksList">
//			<div id="item1">
//				<a id="link1"><img/><span></span></a>
//				<div id="pin1" class="pin"><img/></div>
//			</div>
//		</div>

		//icon
		var img = document.createElement("img");
		img.className="icon";
		// override icon preview for known file types
		if (mostRecentFile.isFolder)
		{// for folders
			if (mostRecentFile.path.substring(0,2)=="\\\\") // is network folder
			{
				img.src="gimage:///"+encodeURIComponent(System.Gadget.path+iconPath["network"]);//+" ?width="+ICON_HEIGHT;
			}
			else
			{	// is local folder
				img.src="gimage:///"+encodeURIComponent(System.Gadget.path+iconPath["folder"]);//+" ?width="+ICON_HEIGHT;
			}
		}
		else
		{// for files
			var extension = mostRecentFile.path.slice(mostRecentFile.path.lastIndexOf(".")+1).toLowerCase();
			if (iconPath[extension])	// if its a file with a known extension
			{
				img.src="gimage:///"+encodeURIComponent(System.Gadget.path+iconPath[extension]);//+" ?width="+ICON_HEIGHT;
			}
			else
			{
				img.src="gimage:///"+encodeURIComponent(mostRecentFile.path);//+" ?width="+ICON_HEIGHT;
			}
		}	
		
		
		img.style.width=ICON_WIDTH;	// setting icon size again, in case path is unavailable, the cross icon is ugly.
		img.style.height=ICON_HEIGHT;
		
		//pin
		var divElement = document.createElement("div");
		var imgElement = document.createElement("img");
		divElement.appendChild(imgElement); // box the img in the div
		if (recentItemsObj.isPinned(mostRecentFile))
		{
			imgElement.src = "../images/pin_pinned.png";	
		}
		else
		{
			imgElement.src = "../images/pin_unpinned.png";	
		}
		divElement.onmousedown = "togglePin('"+i+"')";//"setTimeout(\"showPin('"+i+"')\",1000)"; //setTimeout("showPin(i)",2000)
		divElement.id="pin"+i;
		divElement.style.display="none";
		divElement.className="pin";
		divElement.onmouseover = "highlightPin('"+i+"')";
		divElement.onmouseout = "unhighlightPin('"+i+"')";
		//imgElement.style.height= ICON_HEIGHT;
		//imgElement.style.width= ICON_WIDTH;
		
		//li
		var liElement = document.createElement("div");
		//liElement.className = "item";
		liElement.id="item"+i;
		liElement.onmouseover = "showPin('"+i+"')";//"this.finch = setTimeout(\"showPin('"+i+"')\",1000)"; //"showPin('"+i+"')";//"setTimeout(\"showPin('"+i+"')\",1000)"; //setTimeout("showPin(i)",2000)
		liElement.onmouseout = "hidePin('"+i+"')";
		if (mostRecentFile.isFileSystem)
		{
			liElement.className = "fileItem";
		}
		if (mostRecentFile.isFolder)
		{
			//newHeight+=7;	// dependent on default.css a.folder
			liElement.className = "folderItem";
		}	
		
		//a		
		var linkElement = document.createElement("a");
		linkElement.onmouseover = "highlightItem('"+i+"')";
		linkElement.onmouseout = "unhighlightItem('"+i+"')";
		linkElement.href=linkSrc;
		linkElement.title = mostRecentFile.path;
		linkElement.id="link"+i;

		
		
		//span
		var spanElement = document.createElement("span");
		spanElement.className="fileName";
		spanElement.innerText = fileName;
		
		
		// follow the icon with the text
		linkElement.appendChild(img);	//img in a
		linkElement.appendChild(spanElement);	//span in a
		
		// export DOM elements to the page		
		liElement.appendChild(linkElement); //a in li
		liElement.appendChild(divElement);	//div(pin) after a
		ulElement.appendChild(liElement);	//li in ul  

		
	}
	
	oldUlElement.innerHTML=ulElement.innerHTML;	// clear old data
	
	
	if (recentItemsObj.pathList.length <1)	// if no recent items are present
	{
		ulElement.innerText=STR_NO_RECENT_ITEMS;
		newHeight=50;
	}
	// update the height of the gadget
	linksDiv.style.height=newHeight;
	resize();
}

function highlightItem(id)
{
	document.getElementById("item"+id).style.backgroundImage = "url(" + IMG_ITEM_HIGHLIGHT + ")";
    document.body.focus();	// allows the tooltip popup to show the full path location. works sometimes, but better than nothing
}

function unhighlightItem(id)
{
	document.getElementById("item"+id).style.backgroundImage = "none";
	//document.getElementById("item"+id).style.backgroundColor = "Transparent";
}

function showPin(id)
{
	// shrink the link to fit
	var linkElement= document.getElementById("link"+id);
	linkElement.style.width=WIDTH - PIN_WIDTH -9;
	
	
	//unhide the pin
	var divElement = document.getElementById("pin"+id);
	divElement.style.display="inline";
	
	
}

function togglePin(id)
{
	var itemToPin = recentItemsObj.pathList[id];
	var imgElement = document.getElementById("pin"+id).firstChild;
	if (imgElement.src.indexOf("pin_pinned.png") >-1)
	{
		imgElement.src = "../images/pin_unpinned.png";
		recentItemsObj.unpinPath(itemToPin);
	}
	else
	{
		imgElement.src = "../images/pin_pinned.png";
		recentItemsObj.pinPath(itemToPin);
	}
}

function hidePin(id)
{
	//expand the link
	var linkElement= document.getElementById("link"+id);
	linkElement.style.width= "100%";

	//hide the pin
	var divElement = document.getElementById("pin"+id);
	divElement.style.display="none";
}

function highlightPin(id)
{
	//document.getElementById("pin"+id).style.backgroundColor = "white";
	document.getElementById("pin"+id).style.backgroundImage = "url(" + IMG_PIN_HIGHLIGHT + ")";
}

function unhighlightPin(id)
{
	//document.getElementById("pin"+id).style.backgroundColor = "Transparent";
	document.getElementById("pin"+id).style.backgroundImage = "none";
}

function resize()
{
	gBackground.style.height=linksDiv.style.pixelHeight + webContentDiv.style.pixelHeight;
	document.body.style.height = gBackground.style.pixelHeight+3;
}

function pathExists(path)
{ // this takes very long if checking for a non existant unc path
   try { System.Shell.itemFromPath(path); }
   catch (notFound) { return false; }     
          
   return true;
}


function executeCommand(value)
{
	System.Shell.execute(decodeURIComponent(value)); /* Execute the desired application */
	//System.Shell.execute(value); /* Execute the desired application */
}


window.setTimeout(refresh, refreshTimerMsec);
var timerRunning = true;

function refresh()
{
	timerRunning = false;
	if (!System.Gadget.visible )
	{return;}
	
	// refresh only if a new item is in the recent items folder
	// commenting this check out will increase refresh rate, decrease perf, bring newer items at the top
	if (recentItemsObj.numCurrItems != recentItemsObj.folderItem.SHFolder.Items.count)
	{
		// refresh data
		recentItemsObj.refresh();
	
		// refresh UI
		populate();

	}
	
	window.setTimeout(refresh, refreshTimerMsec);
	timerRunning = true;
}

System.Gadget.visibilityChanged = function ()
{
	if (System.Gadget.visible && !timerRunning)
	{
		window.setTimeout(refresh, refreshTimerMsec);
	}
}


function dockGadget()
{
    var oBody = document.body.style;
	oBody.width = WIDTH ;
	content.style.width = WIDTH-4; //-4 to disallow text overflow into border
	
	gBackground.style.left=0;
	gBackground.style.width=WIDTH;
	gBackground.style.top=0;
	gBackground.style.height=linksDiv.style.pixelHeight + webContentDiv.style.pixelHeight;
	oBody.height = gBackground.style.pixelHeight+3;
	gBackground.addShadow("black",3, 70,0,3); // remove shadow
	//gBackground.softEdge=2;
	//gBackground.blur=5;
	//gBackground.brightness=90;
	
    showOrHide("docked", true);
    showOrHide("undocked", false);
}

function undockGadget()
{
    // TODO: add your undocking functions here
    var oBody = document.body.style;
	oBody.width = WIDTH+5;	//+5 to allow shadow
	content.style.width = WIDTH-4;	//-4 to disallow text overflow into border
	
	gBackground.style.height = linksDiv.style.pixelHeight + webContentDiv.style.pixelHeight;
	oBody.height = gBackground.style.pixelHeight+3;	//+3 to allow for shadow

	gBackground.style.left=0;
	gBackground.style.width=WIDTH;
	gBackground.style.top=0;
	gBackground.addShadow("black", 5, 70,3,3);
	
    showOrHide("undocked", true);
    showOrHide("docked", false);
}

function checkDockState()
{
    if (System.Gadget.docked) {
        dockGadget();
    }
    else {
        undockGadget();
    }
}

function showOrHide(oHTMLElement, bShowOrHide) 
{
  try 
  {
	if (typeof(oHTMLElement)=="string") 
	{ 
	  oHTMLElement = document.getElementById(oHTMLElement); 
	}
	if (oHTMLElement && oHTMLElement.style) 
	{
	  if (bShowOrHide == 'inherit') 
	  {
		oHTMLElement.style.visibility = 'inherit';
	  } 
	  else 
	  {
		if (bShowOrHide)
		{
		  oHTMLElement.style.visibility = 'visible';
		}
		else
		{
		  oHTMLElement.style.visibility = 'hidden';
		}
		try 
		{
		  if (bShowOrHide)
		  {
			oHTMLElement.style.display = 'block';
		  }
		  else
		  {
			oHTMLElement.style.display = 'none';
		  }
		}
		catch (ex) 
		{
		}
	  }
	}
  }
  catch (ex) 
  {
  }
}

function flyout()
{
    System.Gadget.Flyout.file = "flyout.html";
    selectedItem = window.event.srcElement;
    System.Gadget.Flyout.show = true;   
}


	
function folderItems(folderPath)
{
	this.pinnedPathList = _initPinnedPathList();
	this.pathList = [];	// list of path strings
	this.folderItem = System.Shell.itemFromPath(folderPath);
	this.numCurrItems =0;	// the number of items at the time of last refresh	
	
	function _initPinnedPathList()
	{
		var result = new Array();
		var pinnedPathListStr = System.Gadget.Settings.read("pinnedPathList");
		
		// parse the string
		if (pinnedPathListStr != '')
		{
			var pinnedPathList = pinnedPathListStr.split("|");	// tokenize by |
			
			for (var i in pinnedPathList)
			{
				try
				{
					result.push(System.Shell.itemFromPath(pinnedPathList[i]));
				} catch (notFound)
				{// if not available, skip this path
					continue;
				}
			}
		}
		
		return result;
	}

	// loop in pathList and find if path exists in the list
	this.isPinned = function(path)
	{
		for (var i in this.pinnedPathList)
		{
			if (this.pinnedPathList[i].path.toLowerCase() == path.path.toLowerCase())
			{
				return true;
			}
		}
		
		return false;
	}	
	
	// append the path to the pinned list
	this.pinPath = function(path)
	{
		this.pinnedPathList.push(path);
		this.savePinnedPathList();
	}
	
	this.savePinnedPathList = function()
	{
		var str = "";
		for (var i in this.pinnedPathList)
		{
			str = str + this.pinnedPathList[i].path + "|";
		}
		System.Gadget.Settings.write("pinnedPathList",str);
	}
	
	// remove path from pinned list
	this.unpinPath = function(path)
	{
		for (var i in this.pinnedPathList)
		{
			if (this.pinnedPathList[i].path.toLowerCase() == path.path.toLowerCase())
			{
				this.pinnedPathList.splice(i,1);	// remove this guy
			}
		}
		this.savePinnedPathList();
	}
	
	this.refresh = function()
	{
		// this.pinnedPathList = _initPinnedPathList(); //use for debugging only
		this.numCurrItems = this.folderItem.SHFolder.Items.count;	// num items in folder
		var numItems = System.Gadget.Settings.read("numItems");	// num items in settings
		
		var folderList = new folderStructure();
		
		var pinI=0;	// keeps track of number of items from the pinned items list that have been added to the ds
		var folderI = 0;	//keeps track of the number of items from the folder list that have been added to the ds
		
		for (;folderList.length<numItems && folderI<this.numCurrItems;)	//for each item until the numitems in settings, or the numitems in folder, whichever comes first
		{
			// first add the pinned items, then the others
			if (pinI < this.pinnedPathList.length)	// if there are pinned items
			{
				SHtarget = this.pinnedPathList[pinI];
				pinI++;	
			}
			else
			{	// there are no more pinned items
				// get the item
				var SHitem = this.folderItem.SHFolder.Items.item(folderI);
				var SHtarget = SHitem.link.target;// grab its target			
				folderI++;
				
				if (this.isPinned(SHtarget))	// skip items that have already been added
					continue;
			}	
			
			folderList.addItem(SHtarget);
		}
		
		// flatten folderList into pathList
		this.pathList = folderList.getFlatList();
	}
	
}//end class


function folderStructure()
{
	this.length = 0;
	this.folderList = new Array();
	
	this.addItem = function(item)
	{
		if (item.isFolder)
		{
			this.addFolder(item.path.toLowerCase());	// add folder only accepts strings
		}
		else
		{
			this.addFile(item);
		}
	}
	
	// item should be a string
	this.addFolder = function(folderPath)
	{
		//var folderPath = item.path.toLowerCase();
		
		// create a new array if this is the first time we are encountering a file in this folder
		if (!this.folderList[folderPath])	
		{
			this.folderList[folderPath] = new Array();
			this.length++;
		}
	}
	
	this.addFile = function(item)
	{
		// get the parent path
				var parent = item.path.substring(0,item.path.lastIndexOf("\\" ));
				parent = parent.toLowerCase();	//allow case insensitivity while searching
		
		this.addFolder(parent);
		
		// add this file to the array in its hash
				this.folderList[parent].push(item);
		
				this.length++;	// only once added, increment the path list pointer		
				
	}
	
	this.getFlatList =function()
	{
		// flatten folderList into pathList
		var pathList = new Array();
		var i =0;	// keeps track of the pathlist index
		for (var folderPathKey in this.folderList)
		{
			// See if the folder is available
			try
			{
				pathList[i] = System.Shell.itemFromPath(folderPathKey);
			} catch (notFound)
			{// if not available, skip this folder
				continue;
			}
			// if the folder is available, increment
			i++;
			
			for (var itemKey in this.folderList[folderPathKey])	// for each item in the folder
			{
				pathList[i]=this.folderList[folderPathKey][itemKey];
				i++;
			}
		}
		
		return pathList;
	}	
}

function webContent (webpage)
{
	this.updateurl=webpage;
	webContent.response="";
	webContent.height = 0;
	
	this.isUpdated = function()
	{
		if (webContent.response=="") return false;
		else return true;
	}
	
	this.getWebContent = function ()
	{
		return webContent.response;
	}

	this.updateWebContent = function()
	{
		webService = new ActiveXObject("Microsoft.XMLHTTP");
		
		webService.onreadystatechange = function() 
		{
			if (webService.readyState == 4)
			{//state 4 indicates that the transaction has completed. If the resource was not found (code 404), or the server experienced an error (500), state 4 will still be reached. 
				if (webService.status == 200 && 
					webService.responseText.indexOf("dumass")>-1)
				{//return code was 200 – success
					// update UI
					webContent.response = webContentDiv.innerHTML = webService.responseText;
					webContent.height = webContentDiv.style.height=35;
					resize();
				}
				else
				{
					// update ui by emptying
					webContent.response = webContentDiv.innerHTML = "";
					webContent.height  = webContentDiv.style.height=0;
					resize();
				}
			}
		};
			 
		webService.open("GET", this.updateurl, true); //Providing the flag 'true' indicates that it should send the request asynchronously.
		webService.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" );	

		webService.send(null);
	}
}

var webTimerID = window.setInterval(webUpdateRefresh, refreshWebTimerMsec);

function webUpdateRefresh()
{	
	webContentObj.updateWebContent();	//update web data
}
